// 学习 工厂模式

#include <iostream>
#include <string>
#include <memory>

using namespace std;

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        cout << "这是一个苹果" << endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        cout << "这是一个香蕉" << endl;
    }
};

//// 简单工厂模式
// class FruitFactory
// {
// public:
//     static shared_ptr<Fruit> create(string name)
//     {
//         if(name == "苹果")
//             return make_shared<Apple>();
//         else if(name == "香蕉")
//             return make_shared<Banana>();
//     }
// };

// // 工厂方法模式
// class FruitFactory
// {
// public:
//     virtual shared_ptr<Fruit> create() = 0;
// };

// class AppleFactory : public FruitFactory
// {
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory
// {
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Banana>();
//     }
// };

class Animal
{
public:
    virtual void name() = 0;
};

class Dog : public Animal
{
public:
    void name() override
    {
        cout << "这是一条土狗" << endl;
    }
};

class Cat : public Animal
{
public:
    void name() override
    {
        cout << "这是一只土猫" << endl;
    }
};

//抽象工厂模式
//创建一个超级工厂抽象类
class Factory
{
public:
    virtual shared_ptr<Fruit> getFruit(const string &name) = 0;   //生产水果
    virtual shared_ptr<Animal> getAnimal(const string &name) = 0;   //生产动物
};

//生产水果的工厂类
class FruitFactory : public Factory
{
public:
    shared_ptr<Fruit> getFruit(const string &name) override
    {
        if(name == "苹果")
            return make_shared<Apple>();
        else if(name == "香蕉")
            return make_shared<Banana>();
        
        return shared_ptr<Fruit>();
    }

    shared_ptr<Animal> getAnimal(const string &name) override
    {
        //生产水果的工厂无法生产动物
        return shared_ptr<Animal>();
    }
};

//生产动物的工厂类
class AnimalFactory : public Factory
{
public:
    shared_ptr<Fruit> getFruit(const string &name) override
    {
        //同理，生产动物的工厂也无法生产水果
        return shared_ptr<Fruit>();
    }

    shared_ptr<Animal> getAnimal(const string &name) override
    {
        if(name == "土狗")
            return make_shared<Dog>();
        else if(name == "土猫")
            return make_shared<Cat>();
        
        return shared_ptr<Animal>();
    }
};

//辅助生产的生产者
class FactoryProducer
{
public:
    static shared_ptr<Factory> getFactory(const string &type)
    {
        if(type == "水果")
            return make_shared<FruitFactory>();
        else if(type == "动物")
            return make_shared<AnimalFactory>();
        else
            return shared_ptr<Factory>();
    }
};

int main()
{
    //// 简单工厂模式
    // shared_ptr<Fruit> pfruit = FruitFactory::create("苹果");
    // pfruit->name();
    // pfruit = FruitFactory::create("香蕉");
    // pfruit->name();

    // //工厂方法模式
    // shared_ptr<FruitFactory> ff(new AppleFactory);
    // shared_ptr<Fruit> fruit = ff->create();
    // fruit->name();
    // ff.reset(new BananaFactory);
    // fruit = ff->create();
    // fruit->name();

    //抽象工厂模式
    shared_ptr<Factory> fFruit = FactoryProducer::getFactory("水果");
    shared_ptr<Fruit> fruit = fFruit->getFruit("苹果");
    fruit->name();
    fruit = fFruit->getFruit("香蕉");
    fruit->name();

    shared_ptr<Factory> fAnimal = FactoryProducer::getFactory("动物");
    shared_ptr<Animal> animal = fAnimal->getAnimal("土狗");
    animal->name();
    animal = fAnimal->getAnimal("土猫");
    animal->name();

    return 0;
}